package org.shangrila.app.wfm.mb;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.annotation.PostConstruct;

import org.primefaces.context.RequestContext;
import org.primefaces.event.DragDropEvent;
import org.primefaces.event.diagram.ConnectEvent;
import org.primefaces.event.diagram.ConnectionChangeEvent;
import org.primefaces.event.diagram.DisconnectEvent;
import org.primefaces.model.diagram.DefaultDiagramModel;
import org.primefaces.model.diagram.Element;
import org.primefaces.model.diagram.Connection;
import org.primefaces.model.diagram.connector.FlowChartConnector;
import org.primefaces.model.diagram.endpoint.BlankEndPoint;
import org.primefaces.model.diagram.endpoint.EndPoint;
import org.primefaces.model.diagram.endpoint.EndPointAnchor;
import org.primefaces.model.diagram.endpoint.RectangleEndPoint;
import org.primefaces.model.diagram.overlay.ArrowOverlay;
import org.primefaces.model.diagram.overlay.LabelOverlay;

@ManagedBean
@ViewScoped
public class WfmDiagramDesign {

	private DefaultDiagramModel model;
	private static int count=1;
	private static int incx=10;
	private static int posx=1;
	private static int posy=5;
    private boolean suspendEvent;

	private Element elment = new Element("", "25em", "10em");

	private List<Element> elements = new ArrayList<Element>();
    
	@PostConstruct
	public void init() {
		model = new DefaultDiagramModel();
		model.setMaxConnections(-1);
		FlowChartConnector connector = new FlowChartConnector();
		connector.setPaintStyle("{strokeStyle:'#C7B097',lineWidth:3}");
		model.setDefaultConnector(connector);
	}
	
	public void onElementDrop(DragDropEvent ddEvent) {
		String dargId = ddEvent.getDropId();
		System.out.println("dargId = " + dargId);
		Map<String, String> params = FacesContext.getCurrentInstance()
				.getExternalContext().getRequestParameterMap();
		String left = params.get(dargId + "_left");
		String top = params.get(dargId + "_top");
		Element elment = new Element("Node"+count++,posx+"em",posy+"em");
		
        EndPoint endPoint = createRectangleEndPoint(EndPointAnchor.LEFT);
        endPoint.setSource(true);
        endPoint.setTarget(true);
        elment.setDraggable(true);
        elment.addEndPoint(endPoint);
        endPoint = createRectangleEndPoint(EndPointAnchor.RIGHT);
        endPoint.setSource(true);
        endPoint.setTarget(true);
        elment.setDraggable(true);
        elment.addEndPoint(endPoint);
		//System.out.println("left = " + left);
		//System.out.println("top = " + top);
		//elment.setId(UUID.randomUUID().toString());
		//System.out.println("elm.id = " + elment.getId());
		model.addElement(elment);
		posx+=incx;
	}
	
    public void rcexecute() {
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Executed", "Using RemoteCommand."));
    }
	  
    private EndPoint createRectangleEndPoint(EndPointAnchor anchor) {
        RectangleEndPoint endPoint = new RectangleEndPoint(anchor);
        endPoint.setScope("network"); 
        endPoint.setSource(true);
        endPoint.setStyle("{fillStyle:'#98AFC7'}");
        endPoint.setHoverStyle("{fillStyle:'#5C738B'}");
         
        return endPoint;
    }
    private static EndPoint createEndPoint(EndPointAnchor anchor) {
    	BlankEndPoint endPoint = new BlankEndPoint(anchor);
        endPoint.setStyle("{fillStyle:'#404a4e'}");
        endPoint.setHoverStyle("{fillStyle:'#20282b'}");         
        return endPoint;
    }

    public void onConnect(ConnectEvent event) {
        if(!suspendEvent) {
            FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Connected", 
                    "From " + event.getSourceElement().getData()+ " To " + event.getTargetElement().getData());
         
            FacesContext.getCurrentInstance().addMessage(null, msg);
         
            RequestContext.getCurrentInstance().update("form:msgs");
            System.out.println("X:"+event.getSourceElement().getX()+"--Y："+event.getSourceElement().getY());
            
            Connection conn = new Connection(event.getSourceElement().getEndPoints().get(1), event.getTargetElement().getEndPoints().get(0));
            conn.getOverlays().add(new ArrowOverlay(8, 8, 1, 1));
            conn.getOverlays().add(new LabelOverlay("conn", "flow-label", 0.5));
            
        }
        else {
            suspendEvent = false;
        }
    }
     
    public void onDisconnect(DisconnectEvent event) {
        FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Disconnected", 
                    "From " + event.getSourceElement().getData()+ " To " + event.getTargetElement().getData());
         
        FacesContext.getCurrentInstance().addMessage(null, msg);
         
        RequestContext.getCurrentInstance().update("form:msgs");
        System.out.println("X:"+event.getSourceElement().getX()+"--Y："+event.getSourceElement().getY());

    }
     
    public void onConnectionChange(ConnectionChangeEvent event) {
        FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Connection Changed", 
                    "Original Source:" + event.getOriginalSourceElement().getData() + 
                    ", New Source: " + event.getNewSourceElement().getData() + 
                    ", Original Target: " + event.getOriginalTargetElement().getData() + 
                    ", New Target: " + event.getNewTargetElement().getData());
         
        FacesContext.getCurrentInstance().addMessage(null, msg);
         
        RequestContext.getCurrentInstance().update("form:msgs");
        suspendEvent = true;
        System.out.println("X:"+event.getOriginalSourceElement().getX()+"--Y："+event.getOriginalSourceElement().getY());

    }
	private Connection createConnection(EndPoint from, EndPoint to, String label) {
		Connection conn = new Connection(from, to);
		conn.getOverlays().add(new ArrowOverlay(20, 20, 1, 1));

		if (label != null) {
			conn.getOverlays().add(new LabelOverlay(label, "flow-label", 0.5));
		}

		return conn;
	}
	

	public DefaultDiagramModel getModel() {
		return model;
	}

	public void setModel(DefaultDiagramModel model) {
		this.model = model;
	}

	public Element getElment() {
		return elment;
	}

	public void setElment(Element elment) {
		this.elment = elment;
	}

	public List<Element> getElements() {
		return elements;
	}

	public void setElements(List<Element> elements) {
		this.elements = elements;
	}
}